package uk.ac.durham.tel.synergynet.covanto.workspace;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;

import uk.ac.durham.tel.synergynet.covanto.LogUtil;
import uk.ac.durham.tel.synergynet.covanto.LogUtil.LogStatus;
import uk.ac.durham.tel.synergynet.covanto.project.model.ProjectInfo;
import uk.ac.durham.tel.synergynet.covanto.workspace.model.WorkspaceRoot;


public class WorkspaceController {
	
	private static WorkspaceController instance;
	private IWorkspaceRoot workspaceRootResource;
	private WorkspaceRoot workspaceRoot;
	private WorkspaceController() {
		initialise();
	}

	private void initialise() {
		assignWorkspaceRootResource();
		createWorkspaceRoot();
	}
	
	private void createWorkspaceRoot() {
		workspaceRoot = new WorkspaceRoot(workspaceRootResource);
	}

	public void dispose() {
		workspaceRoot.dispose();
	}

	private void assignWorkspaceRootResource() {
		workspaceRootResource = ResourcesPlugin.getWorkspace().getRoot();
	}


	public void createProject(String projectName, IProgressMonitor progressMonitor) throws WorkspaceException {
		IProject projectResource = workspaceRootResource.getProject(projectName);
		try {
			projectResource.create(progressMonitor);
		} catch (CoreException e) {
			LogUtil.log(LogStatus.ERROR, "Unable to create a new Study.", e);
			throw new WorkspaceException("Unable to create a new Study.", e);
		}
	}
	
	public static WorkspaceController getInstance() {
		if (instance==null)
			instance = new WorkspaceController();
		return instance;
	}
	
	public void deleteProject(ProjectInfo projectInfo, IProgressMonitor progressMonitor) throws WorkspaceException {
		IProject projectResource = projectInfo.getProjectResource();
		try {
			projectResource.delete(true, false, progressMonitor);
		} catch (CoreException e) {
			LogUtil.log(LogStatus.ERROR, "Unable to delete the Study.", e);
			throw new WorkspaceException("Unable to delete the Study.", e);
		}
	}
	
	public void openProject(ProjectInfo projectInfo, IProgressMonitor progressMonitor) throws WorkspaceException {
		IProject projectResourceToOpen = projectInfo.getProjectResource();
		try {
			closeOtherProjects(projectResourceToOpen, progressMonitor);
			projectResourceToOpen.open(progressMonitor);
		} catch (CoreException e) {
			LogUtil.log(LogStatus.ERROR, "Unable to delete the Study.", e);
			throw new WorkspaceException("Unable to delete the Study.", e);
		}
	}
	
	public void closeProject(ProjectInfo projectInfo, IProgressMonitor progressMonitor) throws WorkspaceException {
		IProject projectResourceToOpen = projectInfo.getProjectResource();
		try {
			projectResourceToOpen.close(progressMonitor);
		} catch (CoreException e) {
			LogUtil.log(LogStatus.ERROR, "Unable to delete the project.", e);
			throw new WorkspaceException("Unable to delete the project.", e);
		}
	}
	

	private void closeOtherProjects(IProject projectResourceToOpen, IProgressMonitor progressMonitor) throws CoreException {
		for (IProject projectResourceEntry : workspaceRootResource.getProjects()) {
			if (projectResourceEntry.isOpen() && projectResourceEntry != projectResourceToOpen)
				projectResourceEntry.close(progressMonitor);
		}
	}

	public void renameProject(ProjectInfo projectInfo, String newName, IProgressMonitor progressMonitor) throws WorkspaceException {
		try {
			IProjectDescription projectDescription = projectInfo.getProjectResource().getDescription();
			projectDescription.setName(newName);
			projectInfo.getProjectResource().move(projectDescription, false, progressMonitor);
		} catch (CoreException e) {
			LogUtil.log(LogStatus.ERROR, "Unable to rename the Study.", e);
			throw new WorkspaceException("Unable to rename the Study.", e);
		}
	}

	public WorkspaceRoot getWorkspaceRoot() {
		return workspaceRoot;
	}
	
	
}
